package thread;

import com.sun.org.apache.xpath.internal.objects.XObject;
import javafx.scene.SnapshotParameters;

/**
 * 有效的缩小同步范围可以再保证并发安全的前提下提高效率
 *
 * 同步块：
   synchronized(同步监视器对象){
       需要多个线程有先后顺序的同步执行的代码片段
   }
 */
public class SyncDemo2 {
    public static void main(String[] args) {
//        Shop shop = new Shop();
        Shop shop1 = new Shop();
        Shop shop2 = new Shop();
        Thread t1 = new Thread("王"){
            public void run(){
//                shop.buy();
                shop1.buy();
            }
        };
        Thread t2 = new Thread("李"){
            public void run(){
//                shop.buy();
                shop2.buy();
            }
        };

        //上述lambda表达式写法:
        //Thread(Runnable r, String name)


        Thread t3 = new Thread(shop1::buy,"范传奇");
        Thread t4 = new Thread(shop2::buy,"王克晶");

        t1.start();
        t2.start();
    }
}

class Shop{
    //public synchronized void buy(){
    /**
        在这种成员方法上使用synchronized修饰，同步监视器对象不可选，默认只能是this
        此时，如果是Shop shop1 = new Shop();Shop shop2;Thread t1;Thread t2的情况
        this依然是在shop1.buy()时为t1,shop2.buy()时为t2
     */

    public void buy(){
        try {
            Thread t = Thread.currentThread();
            System.out.println(t.getName()+"正在挑衣服...");
            Thread.sleep(3000);

//            synchronized(123){} 编译器不通过，同步监视器对象必须是引用类型
//            synchronized(new Object()){} 一定不能使用实例化表达式作为该对象
//            synchronized("hello"){} 字面量具有同步效果，但不是合适的锁对象
            synchronized(this) {
                /**
                 * this在buy方法里，buy在Shop里，this是shop的实例
                 * 上边，shop.buy();是shop调用了buy(), this就指shop
                 * 但是如果两个流，进入的是不同的两个店，this就不会让这两个流加同步锁
                 * t1去shop1买，t2去shop2买，this指的是不同实例，是t1和t2
                 */

                System.out.println(t.getName() + "正在试衣服...");
                Thread.sleep(3000);
            }
            System.out.println(t.getName()+"结账离开");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}


